// UserService.java
// UserService.java
package com.estore.service;

import com.estore.model.User;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.List;
import java.util.ArrayList;
import java.io.*; // 添加IO导入

public class UserService {
    private static final String USER_DATA_FILE = "users.dat"; // 添加数据文件路径
    private final Map<String, User> users = new ConcurrentHashMap<>();
    private final Map<String, String> usernameToIdMap = new ConcurrentHashMap<>(); // 用户名到用户ID的映射
    private final AtomicLong userIdGenerator = new AtomicLong(1000);

    public UserService() {
        loadUserData(); // 在构造函数中加载数据
        // 如果没有加载到数据，则初始化默认数据
        if (users.isEmpty()) {
            initializeDefaultUsers();
        }
    }
/**
 * 重置指定用户的密码
 * @param userId 用户ID
 * @param newPassword 新密码
 * @return 是否重置成功
 */
public boolean resetUserPassword(String userId, String newPassword) {
    User user = users.get(userId);
    if (user != null) {
        user.setPassword(newPassword);
        saveUserData(); // 保存更改到文件
        return true;
    }
    return false;
}

    /**
     * 初始化默认用户数据
     */
    private void initializeDefaultUsers() {
        // 初始化管理员账户
        User admin = new User("admin", "admin", "admin123", User.UserRole.ADMIN);
        admin.setEmail("admin@estore.com");
        admin.setPhone("13800138000");
        admin.setAddress("管理员办公室");
        users.put("admin", admin);
        usernameToIdMap.put("admin", "admin");

        // 初始化测试用户
        User customer = new User("001", "flc", "123", User.UserRole.CUSTOMER);
        customer.setEmail("customer@estore.com");
        customer.setPhone("13900139000");
        customer.setAddress("北京市朝阳区");
        users.put("user001", customer);
        usernameToIdMap.put("flc", "user001");
    }

    /**
     * 保存用户数据到文件
     */
    public void saveData() {
        saveUserData();
    }

    /**
     * 保存用户数据到文件（专用方法）
     */
    private void saveUserData() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(USER_DATA_FILE))) {
            // 创建一个包含所有必要数据的容器对象
            UserDataContainer container = new UserDataContainer(users, usernameToIdMap, userIdGenerator.get());
            oos.writeObject(container);
            System.out.printf("用户数据已保存到 %s%n", USER_DATA_FILE);
        } catch (IOException e) {
            System.err.printf("保存用户数据时出错: %s%n", e.getMessage());
        }
    }

    /**
     * 从文件加载用户数据
     */
    private void loadUserData() {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(USER_DATA_FILE))) {
            UserDataContainer container = (UserDataContainer) ois.readObject();
            users.clear();
            users.putAll(container.users());
            usernameToIdMap.clear();
            usernameToIdMap.putAll(container.usernameToIdMap());
            userIdGenerator.set(container.userIdGeneratorValue());
            System.out.printf("用户数据已从 %s 加载%n", USER_DATA_FILE);
        } catch (FileNotFoundException e) {
            System.out.printf("未找到用户数据文件 %s，将创建新的数据文件。%n", USER_DATA_FILE);
        } catch (IOException | ClassNotFoundException e) {
            System.err.printf("加载用户数据时出错: %s%n", e.getMessage());
        }
    }

    // 内部类用于序列化所有用户相关数据
    private record UserDataContainer(Map<String, User> users, Map<String, String> usernameToIdMap,
                                     long userIdGeneratorValue) implements Serializable {
        @Serial
        private static final long serialVersionUID = 1L;
    }

    /**
     * 根据消费金额扣除积分
     * @param userId 用户ID
     * @param amount 消费金额
     * @return 更新后的用户对象
     */
    public User deductPointsByAmount(String userId, double amount) {
        User user = findUserById(userId);
        if (user != null) {
            int pointsToDeduct = (int) (amount / 10);
            int currentPoints = user.getPoints();
            int newPoints = currentPoints - pointsToDeduct;

            // 确保积分不会变成负数
            user.setPoints(Math.max(newPoints, 0));

            // 检查是否需要降级VIP用户
            if (user.getRole() == User.UserRole.VIP && user.getPoints() < 1000) {
                user.setRole(User.UserRole.CUSTOMER);
            }

            saveUserData(); // 保存积分扣除后的数据
            return user;
        }
        return null;
    }


    /**
     * 用户注册
     * @param username 用户名
     * @param password 密码
     * @param email 邮箱
     * @return 注册的用户对象
     */
    public User register(String username, String password, String email) {
        // 检查用户名是否已存在
        if (usernameToIdMap.containsKey(username)) {
            throw new IllegalArgumentException("用户名已存在");
        }

        // 生成用户ID
        String userId = "U%d".formatted(userIdGenerator.incrementAndGet());

        // 创建用户（实际项目中应加密密码）
        User user = new User(userId, username, password, User.UserRole.CUSTOMER);
        user.setEmail(email);
        users.put(userId, user);
        usernameToIdMap.put(username, userId);
        saveUserData(); // 保存新注册用户

        return user;
    }

    /**
     * 用户登录
     * @param username 用户名
     * @param password 密码
     * @return 登录成功的用户对象，失败返回null
     */
    public User login(String username, String password) {
        String userId = usernameToIdMap.get(username);
        if (userId == null) {
            return null;
        }

        User targetUser = users.get(userId);
        // 用户不存在
        if (targetUser == null) {
            return null;
        }

        // 检查账户是否被锁定（锁定10分钟后自动解锁）
        if (targetUser.isLocked()) {
            if (targetUser.getLastFailedLoginTime() != null &&
                LocalDateTime.now().isAfter(targetUser.getLastFailedLoginTime().plusMinutes(10))) {
                // 解锁账户
                targetUser.setLocked(false);
                targetUser.setFailedLoginAttempts(0);
            } else {
                // 仍然锁定
                return null;
            }
        }

        // 验证密码
        if (targetUser.getPassword().equals(password)) {
            // 登录成功，重置失败次数
            targetUser.setFailedLoginAttempts(0);
            saveUserData(); // 保存登录成功状态
            return targetUser;
        } else {
            // 登录失败，增加失败次数
            targetUser.incrementFailedLoginAttempts();
            targetUser.setLastFailedLoginTime(LocalDateTime.now());

            // 失败次数达到3次则锁定账户
            if (targetUser.getFailedLoginAttempts() >= 3) {
                targetUser.setLocked(true);
            }
            saveUserData(); // 保存登录失败状态
            return null;
        }
    }

    /**
     * 根据用户ID查找用户
     * @param userId 用户ID
     * @return 用户对象
     */
    public User findUserById(String userId) {
        return users.get(userId);
    }

    /**
     * 更新用户信息
     * @param userId 用户ID
     * @param email 邮箱
     * @param phone 电话
     * @param address 地址
     * @return 更新后的用户对象
     */
    public User updateUserInfo(String userId, String email, String phone, String address) {
        User user = users.get(userId);
        if (user != null) {
            user.setEmail(email);
            user.setPhone(phone);
            user.setAddress(address);
            saveUserData(); // 调用专门的保存方法
            return user;
        }
        return null;
    }



    /**
     * 修改密码
     * @param userId 用户ID
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 是否修改成功
     */
    public boolean changePassword(String userId, String oldPassword, String newPassword) {
        User user = users.get(userId);
        if (user != null && user.getPassword().equals(oldPassword)) {
            user.setPassword(newPassword);
            saveUserData(); // 调用专门的保存方法
            return true;
        }
        return false;
    }

    /**
     * 获取所有用户
     * @return 用户列表
     */
    public List<User> getAllUsers() {
        return new ArrayList<>(users.values());
    }

    /**
     * 删除用户
     * @param userId 用户ID
     * @return 是否删除成功
     */
    public boolean deleteUser(String userId) {
        if (userId.equals("admin")) {
            return false; // 不允许删除管理员账户
        }
        User user = users.remove(userId);
        if (user != null) {
            usernameToIdMap.remove(user.getUsername());
            saveUserData(); // 保存删除用户后的数据
            return true;
        }
        return false;
    }

    /**
     * 更新用户角色
     * @param userId 用户ID
     * @param role 新角色
     * @return 是否更新成功
     */
    public boolean updateUserRole(String userId, User.UserRole role) {
        User user = users.get(userId);
        if (user != null) {
            user.setRole(role);
            saveUserData(); // 保存角色更新后的数据
            return true;
        }
        return false;
    }

    /**
     * 更新用户积分
     * @param userId 用户ID
     * @param points 积分变化值（可为负数）
     * @return 更新后的用户对象
     */
    /**
     * 更新用户积分
     * @param userId 用户ID
     * @param points 积分变化值（可为负数）
     * @return 更新后的用户对象
     */
    public User updatePoints(String userId, int points) {
        User user = users.get(userId);
        if (user != null) {
            // 确保积分不会变成负数
            int newPoints = user.getPoints() + points;
            user.setPoints(Math.max(newPoints, 0));

            // 根据积分自动升级/降级用户等级
            if (user.getPoints() >= 1000 && user.getRole() == User.UserRole.CUSTOMER) {
                user.setRole(User.UserRole.VIP);
            } else if (user.getPoints() < 1000 && user.getRole() == User.UserRole.VIP) {
                user.setRole(User.UserRole.CUSTOMER);
            }

            saveUserData(); // 保存积分更新后的数据
            return user;
        }
        return null;
    }

    /**
     * 解锁用户账户
     * @param userId 用户ID
     * @return 是否解锁成功
     */
    public boolean unlockUser(String userId) {
        User user = users.get(userId);
        if (user != null) {
            user.setLocked(false);
            user.setFailedLoginAttempts(0);
            saveUserData(); // 保存解锁后的数据
            return true;
        }
        return false;
    }

    /*
      检查用户会话是否过期
      @param userId 用户ID
     * @return 是否过期
     */

    /**
     * 更新用户积分（基于消费金额）
     * @param userId 用户ID
     * @param amount 消费金额
     * @return 更新后的用户对象
     */
    public User addPointsByAmount(String userId, double amount) {
        int points = (int) (amount);
        return updatePoints(userId, points);
    }

    /**
     * 刷新用户会话时间
     * @param userId 用户ID
     */
    @SuppressWarnings("unused")
    public void refreshSession(String userId) {
        User user = users.get(userId);
        if (user != null) {
            // 这里可以添加会话刷新逻辑，比如更新最后活动时间
            // 目前为空实现，因为当前系统不需要会话管理
        }
    }
}
